﻿using System;
using System.Windows;
using System.Windows.Browser;
using Microsoft.Silverlight.Testing;
using Microsoft.Silverlight.Testing.Harness.Service;
using Microsoft.Silverlight.Testing.UI;
using Microsoft.Silverlight.Testing.UnitTesting.Harness;
using Microsoft.Silverlight.Testing.UnitTesting.UI;

namespace Objectware.Silverlight.Testing.TestProject
{
	public partial class App : Application
	{
		private static readonly TestResultService.TestResultService TestResultService =
				ServiceLocator.Default.GetInstance<TestResultService.TestResultService>();


		public App()
		{
			this.Startup += this.Application_Startup;
			this.Exit += this.Application_Exit;
			this.UnhandledException += this.Application_UnhandledException;

			InitializeComponent();
		}

		private void Log(string format, params object[] parameters)
		{
			string theString = string.Format(format, parameters);
			//TestResultService.BeginLog(theString, (o) => TestResultService.EndLog(o), null);
		}


		private void Application_Startup(object sender, StartupEventArgs e)
		{
			Log("SL : Application_Startup");


			TestResultService.BeginBeginRun(
				(o) =>
				{
					TestResultService.EndBeginRun(o);
					Log("SL : BeginRun called");
				}, null);


			Log("SL : Setup testproject");
			string testXap = HtmlPage.Document.QueryString["TestProject"];

			Log("SL : TextXAP '{0}'", testXap);
			Uri source = Application.Current.Host.Source;

			SubApplicationHelper.LoadTestAssemblyFromXapAsync(testXap,
				 (ss, ee) =>
				 {
					 Log("SL : Setting up unit testing");
					 var settings = new UnitTestSettings();
					 settings.TestHarness = new UnitTestHarness();
					 settings.TestService = new SilverlightTestService();


					 var element = HtmlPage.Document.GetElementById("MethodsToTest");
					 if (null != element)
					 {
						 var methodsToTest = element.GetAttribute("innerText");
						 settings.TagExpression = methodsToTest;
					 }


					 if (HtmlPage.IsEnabled)
					 {
						 settings.LogProviders.Add(new WebpageHeaderLogProvider("Microsoft.Silverlight.Testing"));
						 settings.LogProviders.Add(new UnitTestWebpageLog());
						 settings.LogProviders.Add(new TextFailuresLogProvider());
						 settings.LogProviders.Add(new UnitTestResultProvider());
					 }

					 settings.TestAssemblies.Add(ee.Assembly);

					 settings.TestHarness.TestHarnessCompleted +=
						 CurrentHarness_TestHarnessCompleted;


					 Log("SL : Creating test page");

					 this.RootVisual = UnitTestSystem.CreateTestPage(settings);

					 Log("SL : Tests should be running now");
				 });
		}


		void CurrentHarness_TestHarnessCompleted(object sender, Microsoft.Silverlight.Testing.Harness.TestHarnessCompletedEventArgs e)
		{
			Log("SL - We're all done");
			ServiceHelper.ExecuteMethod(() => TestResultService.BeginEndRun((o) => TestResultService.EndEndRun(o), null));
		}

		private void Application_Exit(object sender, EventArgs e)
		{

		}

		private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
		{
			// If the app is running outside of the debugger then report the exception using
			// the browser's exception mechanism. On IE this will display it a yellow alert 
			// icon in the status bar and Firefox will display a script error.
			if (!System.Diagnostics.Debugger.IsAttached)
			{

				// NOTE: This will allow the application to continue running after an exception has been thrown
				// but not handled. 
				// For production applications this error handling should be replaced with something that will 
				// report the error to the website and stop the application.
				e.Handled = true;

				try
				{
					string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace;
					errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n");

					System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight 2 Application " + errorMsg + "\");");
				}
				catch (Exception)
				{
				}
			}
		}
	}
}
